package com.micro.ai.template.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.micro.ai.commons.exception.BusinessException;
import com.micro.ai.template.client.AuthClient;
import com.micro.ai.template.dto.request.TemplateCreateRequest;
import com.micro.ai.template.dto.request.TemplateUpdateRequest;
import com.micro.ai.template.dto.response.TemplateDTO;
import com.micro.ai.template.entity.Template;
import com.micro.ai.template.entity.TemplateCategory;
import com.micro.ai.template.mapper.TemplateCategoryMapper;
import com.micro.ai.template.mapper.TemplateMapper;
import com.micro.ai.template.service.TemplateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Slf4j
@Service
public class TemplateServiceImpl extends ServiceImpl<TemplateMapper, Template> implements TemplateService {

    @Autowired
    private TemplateMapper templateMapper;

    @Autowired
    private TemplateCategoryMapper categoryMapper;

    @Autowired
    private AuthClient authClient;

    @Override
    @Transactional
    public TemplateDTO createTemplate(String userId, String tenantId, TemplateCreateRequest request) {
        try {
            // 1. 验证模板名称唯一性（租户内唯一）
            LambdaQueryWrapper<Template> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Template::getTenantId, tenantId)
                   .eq(Template::getTemplateName, request.getTemplateName());
            Template existing = templateMapper.selectOne(wrapper);
            if (existing != null) {
                throw new BusinessException("T0001", "模板名称已存在");
            }

            // 2. 验证分类是否存在
            TemplateCategory category = categoryMapper.selectOne(
                new LambdaQueryWrapper<TemplateCategory>()
                    .eq(TemplateCategory::getCategoryId, request.getCategoryId())
            );
            if (category == null) {
                throw new BusinessException("T0002", "分类不存在");
            }

            // 3. 创建模板实体
            Template template = new Template();
            template.setId(UUID.randomUUID().toString().replace("-", ""));
            template.setTemplateId("tpl_" + System.currentTimeMillis());
            template.setTemplateName(request.getTemplateName());
            template.setDescription(request.getDescription());
            template.setCategoryId(request.getCategoryId());
            
            // ✅ 设置租户和用户
            template.setTenantId(tenantId);
            template.setCreatedBy(userId);
            
            template.setAuthor(request.getAuthor());
            template.setLicense(request.getLicense());
            template.setMinSystemVersion(request.getMinSystemVersion());
            template.setEnabled(true);
            template.setIsPublic(request.getIsPublic() != null ? request.getIsPublic() : true);
            template.setStatus("DRAFT");
            template.setViewCount(0);
            template.setDownloadCount(0);
            template.setUseCount(0);
            template.setRatingScore(BigDecimal.ZERO);
            template.setRatingCount(0);
            template.setTags(request.getTags());
            template.setCoverImage(request.getCoverImage());
            template.setCreatedAt(LocalDateTime.now());
            template.setUpdatedAt(LocalDateTime.now());

            // 4. 保存到数据库
            templateMapper.insert(template);

            // 5. 记录审计日志
            recordAuditLog(userId, tenantId, "template:create", template.getTemplateId(), 
                          "创建模板: " + template.getTemplateName());

            // 6. 转换为DTO返回
            return convertToDTO(template);

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("创建模板失败", e);
            throw new BusinessException("T0100", "创建模板失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public TemplateDTO updateTemplate(String userId, String tenantId, String templateId, 
                                     TemplateUpdateRequest request) {
        try {
            // 1. 查询模板
            Template template = templateMapper.selectOne(
                new LambdaQueryWrapper<Template>()
                    .eq(Template::getTemplateId, templateId)
                    .eq(Template::getTenantId, tenantId)
            );
            
            if (template == null) {
                throw new BusinessException("T0003", "模板不存在");
            }

            // 2. 验证权限（只能修改自己的模板，或者有管理权限）
            if (!template.getCreatedBy().equals(userId)) {
                // 可以调用Auth检查是否有管理员权限
                throw new BusinessException("T0004", "无权修改此模板");
            }

            // 3. 更新字段
            if (StringUtils.hasText(request.getTemplateName())) {
                template.setTemplateName(request.getTemplateName());
            }
            if (StringUtils.hasText(request.getDescription())) {
                template.setDescription(request.getDescription());
            }
            if (StringUtils.hasText(request.getCategoryId())) {
                template.setCategoryId(request.getCategoryId());
            }
            if (StringUtils.hasText(request.getAuthor())) {
                template.setAuthor(request.getAuthor());
            }
            if (StringUtils.hasText(request.getLicense())) {
                template.setLicense(request.getLicense());
            }
            if (request.getEnabled() != null) {
                template.setEnabled(request.getEnabled());
            }
            if (request.getIsPublic() != null) {
                template.setIsPublic(request.getIsPublic());
            }
            if (request.getTags() != null) {
                template.setTags(request.getTags());
            }
            if (StringUtils.hasText(request.getCoverImage())) {
                template.setCoverImage(request.getCoverImage());
            }
            
            template.setUpdatedAt(LocalDateTime.now());

            // 4. 保存更新
            templateMapper.updateById(template);
            
            // 5. 记录审计日志
            recordAuditLog(userId, tenantId, "template:update", templateId, 
                          "更新模板: " + template.getTemplateName());

            // 6. 返回结果
            return convertToDTO(template);

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("更新模板失败", e);
            throw new BusinessException("T0101", "更新模板失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional
    public void deleteTemplate(String userId, String tenantId, String templateId) {
        try {
            // 1. 查询模板
            Template template = templateMapper.selectOne(
                new LambdaQueryWrapper<Template>()
                    .eq(Template::getTemplateId, templateId)
                    .eq(Template::getTenantId, tenantId)
            );
            
            if (template == null) {
                throw new BusinessException("T0003", "模板不存在");
            }

            // 2. 验证权限
            if (!template.getCreatedBy().equals(userId)) {
                throw new BusinessException("T0004", "无权删除此模板");
            }

            // 3. 软删除
            template.setDeletedAt(LocalDateTime.now());
            templateMapper.updateById(template);

            // 4. 记录审计日志
            recordAuditLog(userId, tenantId, "template:delete", templateId, 
                          "删除模板: " + template.getTemplateName());

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("删除模板失败", e);
            throw new BusinessException("T0102", "删除模板失败：" + e.getMessage());
        }
    }

    @Override
    public TemplateDTO getTemplateById(String templateId) {
        Template template = templateMapper.selectOne(
            new LambdaQueryWrapper<Template>()
                .eq(Template::getTemplateId, templateId)
                .isNull(Template::getDeletedAt)
        );
        
        if (template == null) {
            throw new BusinessException("T0003", "模板不存在");
        }

        // 增加浏览次数
        template.setViewCount(template.getViewCount() + 1);
        templateMapper.updateById(template);

        return convertToDTO(template);
    }

    @Override
    public Page<TemplateDTO> listTemplates(String tenantId, Integer pageNum, Integer pageSize, 
                                          String categoryId, String templateName, String status) {
        LambdaQueryWrapper<Template> wrapper = new LambdaQueryWrapper<>();
        
        // 租户隔离
        wrapper.eq(Template::getTenantId, tenantId);
        
        // 过滤条件
        if (StringUtils.hasText(categoryId)) {
            wrapper.eq(Template::getCategoryId, categoryId);
        }
        if (StringUtils.hasText(templateName)) {
            wrapper.like(Template::getTemplateName, templateName);
        }
        if (StringUtils.hasText(status)) {
            wrapper.eq(Template::getStatus, status);
        }
        
        // 只查询未删除的
        wrapper.isNull(Template::getDeletedAt);
        
        // 排序
        wrapper.orderByDesc(Template::getCreatedAt);

        // 分页查询
        Page<Template> page = templateMapper.selectPage(new Page<>(pageNum, pageSize), wrapper);

        // 转换为DTO
        return convertPageToDTO(page);
    }

    @Override
    public Page<TemplateDTO> getMyTemplates(String userId, String tenantId, Integer pageNum, Integer pageSize) {
        LambdaQueryWrapper<Template> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Template::getTenantId, tenantId)
               .eq(Template::getCreatedBy, userId)
               .isNull(Template::getDeletedAt)
               .orderByDesc(Template::getCreatedAt);

        Page<Template> page = templateMapper.selectPage(new Page<>(pageNum, pageSize), wrapper);
        return convertPageToDTO(page);
    }

    @Override
    @Transactional
    public void updateTemplateStatus(String userId, String tenantId, String templateId, Boolean enabled) {
        Template template = templateMapper.selectOne(
            new LambdaQueryWrapper<Template>()
                .eq(Template::getTemplateId, templateId)
                .eq(Template::getTenantId, tenantId)
        );
        
        if (template == null) {
            throw new BusinessException("T0003", "模板不存在");
        }

        template.setEnabled(enabled);
        template.setUpdatedAt(LocalDateTime.now());
            templateMapper.updateById(template);
            
        recordAuditLog(userId, tenantId, "template:update:status", templateId, 
                      "更新模板状态: " + (enabled ? "启用" : "禁用"));
    }

    @Override
    @Transactional
    public TemplateDTO cloneTemplate(String userId, String tenantId, String templateId) {
        try {
            // 1. 查询原模板
            Template source = templateMapper.selectOne(
                new LambdaQueryWrapper<Template>()
                    .eq(Template::getTemplateId, templateId)
                    .isNull(Template::getDeletedAt)
            );
            
            if (source == null) {
                throw new BusinessException("T0003", "模板不存在");
            }

            // 2. 创建副本
            Template clone = new Template();
            BeanUtils.copyProperties(source, clone, "id", "templateId", "tenantId", 
                                   "createdBy", "createdAt", "updatedAt");
            
            clone.setId(UUID.randomUUID().toString().replace("-", ""));
            clone.setTemplateId("tpl_" + System.currentTimeMillis());
            clone.setTemplateName(source.getTemplateName() + " (副本)");
            clone.setTenantId(tenantId);
            clone.setCreatedBy(userId);
            clone.setStatus("DRAFT");
            clone.setViewCount(0);
            clone.setDownloadCount(0);
            clone.setUseCount(0);
            clone.setRatingScore(BigDecimal.ZERO);
            clone.setRatingCount(0);
            clone.setCreatedAt(LocalDateTime.now());
            clone.setUpdatedAt(LocalDateTime.now());

            // 3. 保存副本
            templateMapper.insert(clone);

            // 4. 记录审计日志
            recordAuditLog(userId, tenantId, "template:clone", clone.getTemplateId(), 
                          "克隆模板: " + source.getTemplateName());

            return convertToDTO(clone);

        } catch (BusinessException e) {
            throw e;
        } catch (Exception e) {
            log.error("克隆模板失败", e);
            throw new BusinessException("T0103", "克隆模板失败：" + e.getMessage());
        }
    }

    /**
     * 记录审计日志
     */
    private void recordAuditLog(String userId, String tenantId, String action, 
                               String resourceId, String description) {
        try {
            Map<String, Object> auditLog = new HashMap<>();
            auditLog.put("userId", userId);
            auditLog.put("tenantId", tenantId);
            auditLog.put("action", action);
            auditLog.put("module", "TEMPLATE");
            auditLog.put("resourceType", "template");
            auditLog.put("resourceId", resourceId);
            auditLog.put("description", description);
            
            authClient.createAuditLog(auditLog);
        } catch (Exception e) {
            log.warn("记录审计日志失败（非关键操作）: {}", e.getMessage());
        }
    }

    /**
     * 转换为DTO
     */
    private TemplateDTO convertToDTO(Template template) {
        TemplateDTO dto = new TemplateDTO();
        BeanUtils.copyProperties(template, dto);
        
        // 获取分类名称
        if (StringUtils.hasText(template.getCategoryId())) {
            TemplateCategory category = categoryMapper.selectOne(
                new LambdaQueryWrapper<TemplateCategory>()
                    .eq(TemplateCategory::getCategoryId, template.getCategoryId())
            );
            if (category != null) {
                dto.setCategoryName(category.getName());
            }
        }
        
        return dto;
    }

    /**
     * 转换分页结果
     */
    private Page<TemplateDTO> convertPageToDTO(Page<Template> page) {
        Page<TemplateDTO> dtoPage = new Page<>();
        BeanUtils.copyProperties(page, dtoPage, "records");
        dtoPage.setRecords(page.getRecords().stream()
                .map(this::convertToDTO)
                .toList());
        return dtoPage;
    }
}
